/* file-utilities.vala
 *
 * Copyright (C) 2010  Richard Talbot-Watkins
 * Copyright (C) 2010  Dave Jeffery
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Authors:
 *  Richard Talbot-Watkins <richtw1@gmail.com>
 * 	Dave Jeffery <david.richard.jeffery@gmail.com>
 */

using Gtk;

/**
 * The purpose of this class is to provide tools that will help ensure the
 * program can load the icons and other resources it needs regardless of 
 * whether its binary was produced using make (and hence is being run from
 * its project directory) or by make install (and therefore these files
 * will be in various OS-specific locations).
 *
 * GIO is used to ensure that paths are created in a non file-system 
 * specific way - *nix could use one of any number of file-systems.
 *
 * @author Richard Talbot-Watkins <richtw1@gmail.com>
 * @author Dave Jeffery <david.richard.jeffery@gmail.com>
 * @version 2010.1225
 * @since 0.1
 */
private static class MonsterDesigner.FileUtilities : GLib.Object {

	/**
	 * First parameter passed to the program upon execution. It contains the 
	 * command used to execute the program.
	 */
	private static string _arg0;

	/**
	 * The setter for arg0 ensures that the data_directory path is set up
	 * as soon as the program is run.
	 */
	public static string arg0 {
		get {
			return _arg0;
		}
		set {
			_arg0 = value;
			set_up_paths ();
		}
	}

	/**
	 * File object containing the program's data directory.
	 */
	public static File data_directory;

	/**
	 * This contains the name of the application. The application's icon
	 * should have the same name.
	 */
	private static const string PROGRAM_NAME = "monster-designer";

	/**
	 * The directory in which application icons are stored in uninstalled
	 * packages.
	 */
	private static const string APP_ICON_FOLDER = "apps";

	/**
	 * The directory in which action icons are stored. Action icons depict 
	 * "actions" that the user can do e.g. fill, draw, etc.
	 */
	private static const string ACTION_ICON_FOLDER = "actions";

	/**
	 * Gets the location of the user's data directory, where it is safe to
	 * save sprite files. For GNOME this will be ~/Documents.
	 *
	 * @return GIO File object containing the user's data directory.
	 */
	public static File get_user_data_directory () {
		return File.new_for_path (Environment.get_user_special_dir 
											(UserDirectory.DOCUMENTS));
	}

	/**
	 * Used to set up the path in which the program can find its 
	 * resources.
	 */
	public static void set_up_paths () {
		/*
		   Sees if the program is installed or not, by looking to see if it
		   can be found in any of the directories in the system's PATH
		   variable. If it isn't, it must be being run from the src
		   directory and not installed.
		 */
		var is_installed = (GLib.Environment.find_program_in_path 
							(PROGRAM_NAME) == null) ? false : true;

		/* Define path for loading anything in the data directory. */
		if (is_installed) {
			/* Binary being run from installation location. */
			data_directory = File.new_for_path (Config.PKGDATADIR);
		} else {
			/* Binary being run from src directory. */
			data_directory = File.new_for_path (arg0);
			data_directory = data_directory.get_parent ().get_parent ()
								.get_child ("data");
		}
	}

	/**
	 * Loads an icon with the given icon name into a Gdk.Pixbuf.
	 *
	 * The method used to load the icon is very different depending on
	 * whether the binary is installed or being run from the project 
	 * folder.
	 *
	 * If the program is installed we should try and find the icon in the
	 * default theme - for GNOME that would be "hicolor". If the program 
	 * is not installed we should load the icon as a PNG file from the
	 * project's data folder.
	 * 
	 * The default size for GNOME tool icons is currently 22 pixels.
	 *
	 * @param icon_name Name of the icon to load - no file extention.
	 * @param icon_size Size of the icon to return if possible (in pixels).
	 * @return A Gdk.Pixbuf containing the icon or null if it's not found.
	 */
	public static Gdk.Pixbuf? load_icon (string icon_name, 
											int icon_size=22) {
		/* You shouldn't add a reference to the default theme object. */
		unowned IconTheme icon_theme = IconTheme.get_default ();

		Gdk.Pixbuf pixbuf = null;			
		var icon_flags = 0;

		/* Tries to load icon from the default icon theme. */
		try {			
			pixbuf = icon_theme.load_icon (icon_name, icon_size, icon_flags);
			return pixbuf;
		} catch (Error e) {
			stderr.printf("Can't find %s in icon theme, trying project folder.\n",
				icon_name);
		}

		/* The program isn't installed, so try and load a local copy. */
		var folder = icon_size.to_string () + "x" + icon_size.to_string ();
		var type = (icon_name == PROGRAM_NAME) ? 
						APP_ICON_FOLDER : ACTION_ICON_FOLDER;
		var icon_path = data_directory.get_child ("icons").get_child (folder)
						.get_child(type).get_child(icon_name + ".png");
		try {
			pixbuf = new Gdk.Pixbuf.from_file (icon_path.get_parse_name ());		
		} catch (Error e) {
			stderr.printf ("%s\n", e.message);
		}

		return pixbuf;
	}
}
